import matplotlib.pyplot as plt
import numpy as np 
def grid(u,n=200):
    tm=tM=1e-7
    xm=xM=u.argv[0]
    for i in u.d:
        a,b=i.domain
        if b==np.inf:
            b=a+2
        if b>tM:
            tM=b
        xm=min(xm,i(a),i(b))
        xM=max(xM,i(a),i(b))
    x=np.linspace(xm,xM,n)
    t=np.linspace(tm,tM,n)
    xx,tt=np.meshgrid(x,t)
    return xx,tt

def show(u,cal=None,show=True):
    temp=cal is not None
    if temp:
        xm,xM,tm,tM=cal['x'].min(),cal['x'].max(),cal['t'].min(),cal['t'].max()
    fig,axs=plt.subplots(1,3,figsize=(15,5))
    fig.suptitle(f'{u.argv}')
    for i in axs[:2]:
        i.autoscale(enable=True, axis='both', tight=True)
    axs[1].set_title('Regional Indication')
    for i in u.d:
        a,b=i.domain
        if a==0:
            a=tm if temp else 1e-7
        if b==np.inf:
            b=tM if temp else a+2
        t=np.linspace(a,b,300)
        axs[1].plot(i(t),t,'k-' if i.d else 'k--',label='SD' if i.d else 'WD')
        axs[1].scatter([i(a), i(b)], [a, b], color='r')
        axs[1].text(i(a), a, f'({i(a):.1f}, {a:.1f})', clip_on=True)  # 标注第一个点
        axs[1].text(i(b), b, f'({i(b):.1f}, {b:.1f})', clip_on=True)  # 标注第二个点
    if u.d:
        axs[1].legend()
    if temp:
        axs[1].set_xlim(xm,xM)
        axs[1].set_ylim(tm,tM)
    axs[0].set_title('Scatter of Solution')
    if temp:
        x,y,z=cal['x'],cal['t'],cal['u']
    else:
        x,y=np.linspace(*axs[1].get_xlim(),200),np.linspace(*axs[1].get_ylim(),200)
        x,y=np.meshgrid(x,y)
        z=u(x,y)
    sc=axs[0].scatter(x, y, c=z, cmap='jet',s=1)
    cbar=fig.colorbar(sc,ax=axs[0])
    cbar.set_label('Solution')
    for i in axs[:2]:
        i.set_xlabel('x')
        i.set_ylabel('t')
    if temp:
        x=np.linspace(xm,xM,300)
    else:
        x=np.linspace(*axs[1].get_xlim(),300)
    axs[2].set_title('Changes in Solution')
    makers=['r-','b--','g-.']
    for i,j in enumerate(u.slice):
         axs[2].plot(x,u(x,j),makers[i],label=f't={j}')
    axs[2].legend()
    axs[2].set_xlabel('x')
    axs[2].set_ylabel('u')
    if show:
        plt.show()
    return fig